

#[cfg(test)]
mod test {
    #[test]
    fn test_match(){
        let get_ok_i32: Result<i32, u32> = Ok(1i32);
        match get_ok_i32 {
            Ok(i) => {
                assert_eq!(1, i);
            },
            Err(_) => {
                assert!(false);
            },
        }

        let get_err_u32:  Result<i32, u32>  = Err(1u32);
        match get_err_u32 {
            Ok(_) => { assert!(false); },
            Err(u) => { assert_eq!(1, u);}, 
        }

    }

    #[test]
    fn test_maps() {

        let expect_val = 1i32;
        let v = Result::<i32, u32>::Ok(expect_val);
        assert!(v.is_ok());
        //assert!(v.contains(&1i32));

        let expect_eval = 100u32;
        let e = Result::<i32, u32>::Err(expect_eval);
        assert!(e.is_err());
        //assert!(e.contains_err(&100u32));
//MAP
        //v.map(op);  from result<T,E> ---> result<op(t), e>
        assert_eq!(expect_val + 1, v.map(|i| i + 1).unwrap());
        //v.map_err(op); from result<T,E> ---> result<T, op(e)>
        assert_eq!(Err(expect_eval+2), e.map_err(|u| u + 2));

        assert_eq!(Ok("4".to_string()), v.map(|i| i + i).map(|i| i + i).map(|i| i.to_string()));

        //v.map_or(default, op):  from result<T, E> --> U
        //  t ->op(t) = U;
        //  e -> default(U);
        assert_eq!(expect_val.to_string(), v.map_or("default".to_owned(), |i| i.to_string()));
        assert_eq!(expect_eval.to_string(), e.map_or(expect_eval.to_string(), |i| i.to_string()));

        //v.map_or_else(op_e, op_t): from result<T, E> --> U
        //  t ->op_t(t)-> U
        //  e ->op_e(e)-> U
        assert_eq!((expect_val+1).to_string(), v.map_or_else(|e| (e + 2).to_string(), |i| (i + 1).to_string()));
        assert_eq!((expect_eval+2).to_string(), e.map_or_else(|e| (e + 2).to_string(), |i| (i + 1).to_string()));

        assert_eq!(expect_val as i64, v.map_or_else(|e| e as i64, |t| t as i64 ));


        
//And 
        // and  from Result<T, E> => Result<U, E>
        //  x.and(y) :
        //      ok -> return y; Result<U,E>
        //      err -> Result<U,E>(x)
        {
            let expect_val_y ="hello";
            let y = Result::<&str, u32>::Ok(expect_val_y);
            assert_eq!(y, v.and(y));
            //Convert Result<T,E> => Result<U, E>
            assert_eq!(Err(expect_eval),  e.and(y));
        }
    

        // and_then from Result<T, E> => Result<U, E>
        // x.and_then(op()) op: (T)-> Result<U,E>
        assert_eq!(Result::<i32, &str>::Ok(2).and_then(|i| Ok(i.to_string())), Ok(2.to_string()));

        assert_eq!(Result::<i32, &str>::Err("not a number").and_then(|i| Ok(i.to_string())), Err("not a number"));

//OR 
        // or from Result<T,E> => Result<T, F>
        // x.or(y)
        //  err -> y <T, F>
        //  ok ->  Result<T, F>::Ok(t)
        {
            let expect_val_y = 1i32;
            let y = Result::<i32, &str>::Ok(expect_val_y);
            assert_eq!(y, e.or(y));
            assert_eq!(Result::<i32, &str>::Ok(expect_val), v.or(y));
        }
        //or_else from Result<T, E> => Result<T, F>
        //x.or_else(op()) op: (e) -> Result<T, F>
        {
            assert_eq!(Result::<i32, &str>::Ok(expect_val), v.or_else(|u| Ok((u + 2) as i32)));
            assert_eq!(Result::<i32, u32>::Ok((expect_eval + 2) as i32), e.or_else(|u| Ok((u + 2) as i32)));
        }
    }

    #[test]
    fn test_cvt_to_option(){
        let expect_val = 1i32;
        let v = Result::<i32, u32>::Ok(expect_val);
        assert!(v.is_ok());

        let expect_eval = 100u32;
        let e = Result::<i32, u32>::Err(expect_eval);
        assert!(e.is_err());

        //ok() -> Option<T>
        assert_eq!(Some(expect_val), v.ok());
        assert_eq!(None, e.ok());

        //err() -> Option<E>
        assert_eq!(None, v.err());
        assert_eq!(Some(expect_eval), e.err());

    }

    #[test]
    fn test_and_then(){
        fn find(key: &str) -> Result<&str, i32>{
            println!("find");
            if key == "exist-key" {
                Ok(key) 
            }
            else {
                Err(-1)  // not exist key eror
            }
        }
        fn delete(key: &str) -> Result<bool, i32> {
            println!("delete");
            if key == "exist-key" {
                Ok(true)
            }
            else {
                Err(-2)
            }
        }
        let key = "string";
        if find(key).is_ok() {
            delete(key).unwrap();
        }
        //assert_eq!(Ok(true), find("exist-key").and_then(|k| delete(k)));
        //assert_eq!(Err(-1), find("not-exist-key").and_then(|k| delete(k)));

        //assert_eq!(Ok(true), find("exist-key").and(delete("exist-key")));
        //assert_eq!(Err(-1), find("not-exist-key").and(delete("not-exist-key")));
        /*
        loop  {
            let k = self.key(key)
            let mut out_k : &str = "";
            self.key("key")
                .and_then( |_| self.separator('='))
                .and_then( |_| self.value()) 
                .map( |v| {
                    if out_k == key { v } else {""}
                })
                .and_then( |_| self.separator(','))
        }*/

        
        //find -> Result<&str, i32>; =>   Result<bool, i32>
        //find(key).and(Result<bool, i32>::Ok(true)).and(Result<f32, i32>::Ok(1.000));
        /* find.and : 1. Ok => res { 
                    1.1 Ok(true) 
                    1.2 Err(i32) 
                  }
                  2. Err(i32) => Err(i32)
        */

        /*
        find -> Result<&str, i32> -> Result<&str, i32>
        find.or :   1. Err(i32) -> Result(T, E)
                    2. Ok(t) -> Ok(t)
        */


    }
    
    #[test]
    fn test_map_map_error(){
    }
}
